﻿(function()
{
    var e, t = this,
        n = t.Backbone,
        i = [],
        o = i.push,
        s = i.slice,
        r = i.splice;
    e = "undefined" !== typeof exports ? exports : t.Backbone = {},
    e.VERSION = "0.9.10";
    var a = t._;
    a || "undefined" === typeof require || (a = require("underscore")),
    e.$ = t.jQuery || t.Zepto || t.ender,
    e.noConflict = function()
    {
        return t.Backbone = n,
        this;
    },
    e.emulateHTTP = !1,
    e.emulateJSON = !1;
    var l = /\s+/,
        u = function(e, t, n, i)
        {
            if (!n)
            {
                return !0;
            }
            if ("object" === typeof n)
            {
                for (var o in n)
                {
                    e[t].apply(e, [o, n[o]].concat(i));
                }
            }
            else
            {
                if (!l.test(n))
                {
                    return !0;
                }
                for (var s = n.split(l), r = 0, a = s.length; r < a; r++)
                {
                    e[t].apply(e, [s[r]].concat(i));
                }
            }
        },
        c = function(e, t)
        {
            var n, i = -1,
                o = e.length;
            switch (t.length)
            {
                case 0:
                    for (; ++i < o;)
                    {
                        (n = e[i]).callback.call(n.ctx);
                    }
                    return;
                case 1:
                    for (; ++i < o;)
                    {
                        (n = e[i]).callback.call(n.ctx, t[0]);
                    }
                    return;
                case 2:
                    for (; ++i < o;)
                    {
                        (n = e[i]).callback.call(n.ctx, t[0], t[1]);
                    }
                    return;
                case 3:
                    for (; ++i < o;)
                    {
                        (n = e[i]).callback.call(n.ctx, t[0], t[1], t[2]);
                    }
                    return;
                default:
                    for (; ++i < o;)
                    {
                        (n = e[i]).callback.apply(n.ctx, t);
                    }
            }
        },
        d = e.Events = {
            on: function(e, t, n)
            {
                if (!u(this, "on", e, [t, n]) || !t)
                {
                    return this;
                }
                this._events || (this._events = {});
                var i = this._events[e] || (this._events[e] = []);
                return i.push({
                    callback: t,
                    context: n,
                    ctx: n || this
                }),
                this;
            },
            once: function(e, t, n)
            {
                if (!u(this, "once", e, [t, n]) || !t)
                {
                    return this;
                }
                var i = this,
                    o = a.once(function()
                    {
                        i.off(e, o),
                        t.apply(this, arguments);
                    });
                return o._callback = t,
                this.on(e, o, n),
                this;
            },
            off: function(e, t, n)
            {
                var i, o, s, r, l, c, d, h;
                if (!this._events || !u(this, "off", e, [t, n]))
                {
                    return this;
                }
                if (!e && !t && !n)
                {
                    return this._events = {},
                    this;
                }
                for (r = e ? [e] : a.keys(this._events), l = 0, c = r.length; l < c; l++)
                {
                    if (e = r[l], i = this._events[e])
                    {
                        if (s = [], t || n)
                        {
                            for (d = 0, h = i.length; d < h; d++)
                            {
                                o = i[d],
                                (t && t !== o.callback && t !== o.callback._callback || n && n !== o.context) && s.push(o);
                            }
                        }
                        this._events[e] = s;
                    }
                }
                return this;
            },
            trigger: function(e)
            {
                if (!this._events)
                {
                    return this;
                }
                var t = s.call(arguments, 1);
                if (!u(this, "trigger", e, t))
                {
                    return this;
                }
                var n = this._events[e],
                    i = this._events.all;
                return n && c(n, t),
                i && c(i, arguments),
                this;
            },
            listenTo: function(e, t, n)
            {
                var i = this._listeners || (this._listeners = {}),
                    o = e._listenerId || (e._listenerId = a.uniqueId("l"));
                return i[o] = e,
                e.on(t, "object" === typeof t ? this : n, this),
                this;
            },
            stopListening: function(e, t, n)
            {
                var i = this._listeners;
                if (i)
                {
                    if (e)
                    {
                        e.off(t, "object" === typeof t ? this : n, this),
                        t || n || delete i[e._listenerId];
                    }
                    else
                    {
                        "object" === typeof t && (n = this);
                        for (var o in i)
                        {
                            i[o].off(t, n, this);
                        }
                        this._listeners = {};
                    }
                    return this;
                }
            }
        };
    d.bind = d.on,
    d.unbind = d.off,
    a.extend(e, d);
    var h = e.Model = function(e, t)
    {
        var n, i = e || {};
        this.cid = a.uniqueId("c"),
        this.attributes = {},
        t && t.collection && (this.collection = t.collection),
        t && t.parse && (i = this.parse(i, t) || {}),
        (n = a.result(this, "defaults")) && (i = a.defaults({},
            i, n)),
        this.set(i, t),
        this.changed = {},
        this.initialize.apply(this, arguments);
    };
    a.extend(h.prototype, d, {
        changed: null,
        idAttribute: "id",
        initialize: function()
        {
        },
        toJSON: function()
        {
            return a.clone(this.attributes);
        },
        sync: function()
        {
            return e.sync.apply(this, arguments);
        },
        get: function(e)
        {
            return this.attributes[e];
        },
        escape: function(e)
        {
            return a.escape(this.get(e));
        },
        has: function(e)
        {
            return null != this.get(e);
        },
        set: function(e, t, n)
        {
            var i, o, s, r, l, u, c, d;
            if (null == e)
            {
                return this;
            }
            if ("object" === typeof e ? (o = e, n = t) : (o = {})[e] = t, n || (n = {}), !this._validate(o, n))
            {
                return !1;
            }
            s = n.unset,
            l = n.silent,
            r = [],
            u = this._changing,
            this._changing = !0,
            u || (this._previousAttributes = a.clone(this.attributes), this.changed = {}),
            d = this.attributes,
            c = this._previousAttributes,
            this.idAttribute in o && (this.id = o[this.idAttribute]);
            for (i in o)
            {
                t = o[i],
                a.isEqual(d[i], t) || r.push(i),
                a.isEqual(c[i], t) ? delete this.changed[i] : this.changed[i] = t,
                s ? delete d[i] : d[i] = t;
            }
            if (!l)
            {
                r.length && (this._pending = !0);
                for (var h = 0,
                    p = r.length; h < p; h++)
                {
                    this.trigger("change:" + r[h], this, d[r[h]], n);
                }
            }
            if (u)
            {
                return this;
            }
            if (!l)
            {
                for (; this._pending;)
                {
                    this._pending = !1,
                    this.trigger("change", this, n);
                }
            }
            return this._pending = !1,
            this._changing = !1,
            this;
        },
        unset: function(e, t)
        {
            return this.set(e, void 0, a.extend({},
                t, {
                    unset: !0
                }));
        },
        clear: function(e)
        {
            var t = {};
            for (var n in this.attributes)
            {
                t[n] = void 0;
            }
            return this.set(t, a.extend({},
                e, {
                    unset: !0
                }));
        },
        hasChanged: function(e)
        {
            return null == e ? !a.isEmpty(this.changed) : a.has(this.changed, e);
        },
        changedAttributes: function(e)
        {
            if (!e)
            {
                return this.hasChanged() ? a.clone(this.changed) : !1;
            }
            var t, n = !1,
                i = this._changing ? this._previousAttributes : this.attributes;
            for (var o in e)
            {
                a.isEqual(i[o], t = e[o]) || ((n || (n = {}))[o] = t);
            }
            return n;
        },
        previous: function(e)
        {
            return null != e && this._previousAttributes ? this._previousAttributes[e] : null;
        },
        previousAttributes: function()
        {
            return a.clone(this._previousAttributes);
        },
        fetch: function(e)
        {
            e = e ? a.clone(e) : {},
            void 0 === e.parse && (e.parse = !0);
            var t = e.success;
            return e.success = function(e, n, i)
            {
                return e.set(e.parse(n, i), i) ? (t && t(e, n, i), void 0) : !1;
            },
            this.sync("read", this, e);
        },
        save: function(e, t, n)
        {
            var i, o, s, r, l = this.attributes;
            return null == e || "object" === typeof e ? (i = e, n = t) : (i = {})[e] = t,
            !i || n && n.wait || this.set(i, n) ? (n = a.extend({
                validate: !0
            },
                    n), this._validate(i, n) ? (i && n.wait && (this.attributes = a.extend({},
                            l, i)), void 0 === n.parse && (n.parse = !0), o = n.success, n.success = function(e, t, n)
                            {
                                e.attributes = l;
                                var s = e.parse(t, n);
                                return n.wait && (s = a.extend(i || {},
                                    s)),
                                a.isObject(s) && !e.set(s, n) ? !1 : (o && o(e, t, n), void 0);
                            },
                    s = this.isNew() ? "create" : n.patch ? "patch" : "update", "patch" === s && (n.attrs = i), r = this.sync(s, this, n), i && n.wait && (this.attributes = l), r) : !1) : !1;
        },
        destroy: function(e)
        {
            e = e ? a.clone(e) : {};
            var t = this,
                n = e.success,
                i = function()
                {
                    t.trigger("destroy", t, t.collection, e);
                };
            if (e.success = function(e, t, o)
            {
                (o.wait || e.isNew()) && i(),
                n && n(e, t, o);
            },
            this.isNew())
            {
                return e.success(this, null, e),
                !1;
            }
            var o = this.sync("delete", this, e);
            return e.wait || i(),
            o;
        },
        url: function()
        {
            var e = a.result(this, "urlRoot") || a.result(this.collection, "url") || M();
            return this.isNew() ? e : e + ("/" === e.charAt(e.length - 1) ? "" : "/") + encodeURIComponent(this.id);
        },
        parse: function(e)
        {
            return e;
        },
        clone: function()
        {
            return new this.constructor(this.attributes);
        },
        isNew: function()
        {
            return null == this.id;
        },
        isValid: function(e)
        {
            return !this.validate || !this.validate(this.attributes, e);
        },
        _validate: function(e, t)
        {
            if (!t.validate || !this.validate)
            {
                return !0;
            }
            e = a.extend({},
                this.attributes, e);
            var n = this.validationError = this.validate(e, t) || null;
            return n ? (this.trigger("invalid", this, n, t || {}), !1) : !0;
        }
    });
    var p = e.Collection = function(e, t)
    {
        t || (t = {}),
        t.model && (this.model = t.model),
        void 0 !== t.comparator && (this.comparator = t.comparator),
        this.models = [],
        this._reset(),
        this.initialize.apply(this, arguments),
        e && this.reset(e, a.extend({
            silent: !0
        },
            t));
    };
    a.extend(p.prototype, d, {
        model: h,
        initialize: function()
        {
        },
        toJSON: function(e)
        {
            return this.map(function(t)
            {
                return t.toJSON(e);
            });
        },
        sync: function()
        {
            return e.sync.apply(this, arguments);
        },
        add: function(e, t)
        {
            e = a.isArray(e) ? e.slice() : [e],
            t || (t = {});
            var n, i, s, l, u, c, d, h, p, f;
            for (d = [], h = t.at, p = this.comparator && null == h && 0 != t.sort, f = a.isString(this.comparator) ? this.comparator : null, n = 0, i = e.length; n < i; n++)
            {
                (s = this._prepareModel(l = e[n], t)) ? (u = this.get(s)) ? t.merge && (u.set(l === s ? s.attributes : l, t), p && !c && u.hasChanged(f) && (c = !0)) : (d.push(s), s.on("all", this._onModelEvent, this), this._byId[s.cid] = s, null != s.id && (this._byId[s.id] = s)) : this.trigger("invalid", this, l, t);
            }
            if (d.length && (p && (c = !0), this.length += d.length, null != h ? r.apply(this.models, [h, 0].concat(d)) : o.apply(this.models, d)), c && this.sort({
                silent: !0
            }), t.silent)
            {
                return this;
            }
            for (n = 0, i = d.length; n < i; n++)
            {
                (s = d[n]).trigger("add", s, this, t);
            }
            return c && this.trigger("sort", this, t),
            this;
        },
        remove: function(e, t)
        {
            e = a.isArray(e) ? e.slice() : [e],
            t || (t = {});
            var n, i, o, s;
            for (n = 0, i = e.length; n < i; n++)
            {
                s = this.get(e[n]),
                s && (delete this._byId[s.id], delete this._byId[s.cid], o = this.indexOf(s), this.models.splice(o, 1), this.length--, t.silent || (t.index = o, s.trigger("remove", s, this, t)), this._removeReference(s));
            }
            return this;
        },
        push: function(e, t)
        {
            return e = this._prepareModel(e, t),
            this.add(e, a.extend({
                at: this.length
            },
                t)),
            e;
        },
        pop: function(e)
        {
            var t = this.at(this.length - 1);
            return this.remove(t, e),
            t;
        },
        unshift: function(e, t)
        {
            return e = this._prepareModel(e, t),
            this.add(e, a.extend({
                at: 0
            },
                t)),
            e;
        },
        shift: function(e)
        {
            var t = this.at(0);
            return this.remove(t, e),
            t;
        },
        slice: function(e, t)
        {
            return this.models.slice(e, t);
        },
        get: function(e)
        {
            return null == e ? void 0 : (this._idAttr || (this._idAttr = this.model.prototype.idAttribute), this._byId[e.id || e.cid || e[this._idAttr] || e]);
        },
        at: function(e)
        {
            return this.models[e];
        },
        where: function(e)
        {
            return a.isEmpty(e) ? [] : this.filter(function(t)
            {
                for (var n in e)
                {
                    if (e[n] !== t.get(n))
                    {
                        return !1;
                    }
                }
                return !0;
            });
        },
        sort: function(e)
        {
            if (!this.comparator)
            {
                throw Error("Cannot sort a set without a comparator");
            }
            return e || (e = {}),
            a.isString(this.comparator) || 1 === this.comparator.length ? this.models = this.sortBy(this.comparator, this) : this.models.sort(a.bind(this.comparator, this)),
            e.silent || this.trigger("sort", this, e),
            this;
        },
        pluck: function(e)
        {
            return a.invoke(this.models, "get", e);
        },
        update: function(e, t)
        {
            t = a.extend({
                add: !0,
                merge: !0,
                remove: !0
            },
                t),
            t.parse && (e = this.parse(e, t));
            var n, i, o, s, r = [],
                l = [],
                u = {};
            if (a.isArray(e) || (e = e ? [e] : []), t.add && !t.remove)
            {
                return this.add(e, t);
            }
            for (i = 0, o = e.length; i < o; i++)
            {
                n = e[i],
                s = this.get(n),
                t.remove && s && (u[s.cid] = !0),
                (t.add && !s || t.merge && s) && r.push(n);
            }
            if (t.remove)
            {
                for (i = 0, o = this.models.length; i < o; i++)
                {
                    n = this.models[i],
                    u[n.cid] || l.push(n);
                }
            }
            return l.length && this.remove(l, t),
            r.length && this.add(r, t),
            this;
        },
        reset: function(e, t)
        {
            t || (t = {}),
            t.parse && (e = this.parse(e, t));
            for (var n = 0,
                i = this.models.length; n < i; n++)
            {
                this._removeReference(this.models[n]);
            }
            return t.previousModels = this.models.slice(),
            this._reset(),
            e && this.add(e, a.extend({
                silent: !0
            },
                t)),
            t.silent || this.trigger("reset", this, t),
            this;
        },
        fetch: function(e)
        {
            e = e ? a.clone(e) : {},
            void 0 === e.parse && (e.parse = !0);
            var t = e.success;
            return e.success = function(e, n, i)
            {
                var o = i.update ? "update" : "reset";
                e[o](n, i),
                t && t(e, n, i);
            },
            this.sync("read", this, e);
        },
        create: function(e, t)
        {
            if (t = t ? a.clone(t) : {},
            !(e = this._prepareModel(e, t)))
            {
                return !1;
            }
            t.wait || this.add(e, t);
            var n = this,
                i = t.success;
            return t.success = function(e, t, o)
            {
                o.wait && n.add(e, o),
                i && i(e, t, o);
            },
            e.save(null, t),
            e;
        },
        parse: function(e)
        {
            return e;
        },
        clone: function()
        {
            return new this.constructor(this.models);
        },
        _reset: function()
        {
            this.length = 0,
            this.models.length = 0,
            this._byId = {};
        },
        _prepareModel: function(e, t)
        {
            if (e instanceof h)
            {
                return e.collection || (e.collection = this),
                e;
            }
            t || (t = {}),
            t.collection = this;
            var n = new this.model(e, t);
            return n._validate(e, t) ? n : !1;
        },
        _removeReference: function(e)
        {
            this === e.collection && delete e.collection,
            e.off("all", this._onModelEvent, this);
        },
        _onModelEvent: function(e, t, n, i)
        {
            ("add" !== e && "remove" !== e || n === this) && ("destroy" === e && this.remove(t, i), t && e === "change:" + t.idAttribute && (delete this._byId[t.previous(t.idAttribute)], null != t.id && (this._byId[t.id] = t)), this.trigger.apply(this, arguments));
        },
        sortedIndex: function(e, t, n)
        {
            t || (t = this.comparator);
            var i = a.isFunction(t) ? t : function(e)
            {
                return e.get(t);
            };
            return a.sortedIndex(this.models, e, i, n);
        }
    });
    var f = ["forEach", "each", "map", "collect", "reduce", "foldl", "inject", "reduceRight", "foldr", "find", "detect", "filter", "select", "reject", "every", "all", "some", "any", "include", "contains", "invoke", "max", "min", "toArray", "size", "first", "head", "take", "initial", "rest", "tail", "drop", "last", "without", "indexOf", "shuffle", "lastIndexOf", "isEmpty", "chain"];
    a.each(f,
        function(e)
        {
            p.prototype[e] = function()
            {
                var t = s.call(arguments);
                return t.unshift(this.models),
                a[e].apply(a, t);
            };
        });
    var m = ["groupBy", "countBy", "sortBy"];
    a.each(m,
        function(e)
        {
            p.prototype[e] = function(t, n)
            {
                var i = a.isFunction(t) ? t : function(e)
                {
                    return e.get(t);
                };
                return a[e](this.models, i, n);
            };
        });
    var g = e.Router = function(e)
    {
        e || (e = {}),
        e.routes && (this.routes = e.routes),
        this._bindRoutes(),
        this.initialize.apply(this, arguments);
    },
        v = /\((.*?)\)/g,
        _ = /(\(\?)?:\w+/g,
        C = /\*\w+/g,
        y = /[\-{}\[\]+?.,\\\^$|#\s]/g;
    a.extend(g.prototype, d, {
        initialize: function()
        {
        },
        route: function(t, n, i)
        {
            return a.isRegExp(t) || (t = this._routeToRegExp(t)),
            i || (i = this[n]),
            e.history.route(t, a.bind(function(o)
            {
                var s = this._extractParameters(t, o);
                i && i.apply(this, s),
                this.trigger.apply(this, ["route:" + n].concat(s)),
                this.trigger("route", n, s),
                e.history.trigger("route", this, n, s);
            },
                this)),
            this;
        },
        navigate: function(t, n)
        {
            return e.history.navigate(t, n),
            this;
        },
        _bindRoutes: function()
        {
            if (this.routes)
            {
                for (var e, t = a.keys(this.routes); null != (e = t.pop());)
                {
                    this.route(e, this.routes[e]);
                }
            }
        },
        _routeToRegExp: function(e)
        {
            return e = e.replace(y, "\\$&").replace(v, "(?:$1)?").replace(_,
                function(e, t)
                {
                    return t ? e : "([^/]+)";
                }).replace(C, "(.*?)"),
            RegExp("^" + e + "$");
        },
        _extractParameters: function(e, t)
        {
            return e.exec(t).slice(1);
        }
    });
    var P = e.History = function()
    {
        this.handlers = [],
        a.bindAll(this, "checkUrl"),
        "undefined" !== typeof window && (this.location = window.location, this.history = window.history);
    },
        T = /^[#\/]|\s+$/g,
        E = /^\/+|\/+$/g,
        S = /msie [\w.]+/,
        b = /\/$/;
    P.started = !1,
    a.extend(P.prototype, d, {
        interval: 50,
        getHash: function(e)
        {
            var t = (e || this).location.href.match(/#(.*)$/);
            return t ? t[1] : "";
        },
        getFragment: function(e, t)
        {
            if (null == e)
            {
                if (this._hasPushState || !this._wantsHashChange || t)
                {
                    e = this.location.pathname;
                    var n = this.root.replace(b, "");
                    e.indexOf(n) || (e = e.substr(n.length));
                }
                else
                {
                    e = this.getHash();
                }
            }
            return e.replace(T, "");
        },
        start: function(t)
        {
            if (P.started)
            {
                throw Error("Backbone.history has already been started");
            }
            P.started = !0,
            this.options = a.extend({},
                {
                    root: "/"
                },
                this.options, t),
            this.root = this.options.root,
            this._wantsHashChange = this.options.hashChange !== !1,
            this._wantsPushState = !!this.options.pushState,
            this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState);
            var n = this.getFragment(),
                i = document.documentMode,
                o = S.exec(navigator.userAgent.toLowerCase()) && (!i || i <= 7);
            this.root = ("/" + this.root + "/").replace(E, "/"),
            o && this._wantsHashChange && (this.iframe = e.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow, this.navigate(n)),
            this._hasPushState ? e.$(window).on("popstate", this.checkUrl) : this._wantsHashChange && "onhashchange" in window && !o ? e.$(window).on("hashchange", this.checkUrl) : this._wantsHashChange && (this._checkUrlInterval = setInterval(this.checkUrl, this.interval)),
            this.fragment = n;
            var s = this.location,
                r = s.pathname.replace(/[^\/]$/, "$&/") === this.root;
            return this._wantsHashChange && this._wantsPushState && !this._hasPushState && !r ? (this.fragment = this.getFragment(null, !0), this.location.replace(this.root + this.location.search + "#" + this.fragment), !0) : (this._wantsPushState && this._hasPushState && r && s.hash && (this.fragment = this.getHash().replace(T, ""), this.history.replaceState({},
                document.title, this.root + this.fragment + s.search)), this.options.silent ? void 0 : this.loadUrl());
        },
        stop: function()
        {
            e.$(window).off("popstate", this.checkUrl).off("hashchange", this.checkUrl),
            clearInterval(this._checkUrlInterval),
            P.started = !1;
        },
        route: function(e, t)
        {
            this.handlers.unshift({
                route: e,
                callback: t
            });
        },
        checkUrl: function()
        {
            var e = this.getFragment();
            return e === this.fragment && this.iframe && (e = this.getFragment(this.getHash(this.iframe))),
            e === this.fragment ? !1 : (this.iframe && this.navigate(e), this.loadUrl() || this.loadUrl(this.getHash()), void 0);
        },
        loadUrl: function(e)
        {
            var t = this.fragment = this.getFragment(e),
                n = a.any(this.handlers,
                    function(e)
                    {
                        return e.route.test(t) ? (e.callback(t), !0) : void 0;
                    });
            return n;
        },
        navigate: function(e, t)
        {
            if (!P.started)
            {
                return !1;
            }
            if (t && t !== !0 || (t = {
                trigger: t
            }), e = this.getFragment(e || ""), this.fragment !== e)
            {
                this.fragment = e;
                var n = this.root + e;
                if (this._hasPushState)
                {
                    this.history[t.replace ? "replaceState" : "pushState"]({},
                        document.title, n);
                }
                else
                {
                    if (!this._wantsHashChange)
                    {
                        return this.location.assign(n);
                    }
                    this._updateHash(this.location, e, t.replace),
                    this.iframe && e !== this.getFragment(this.getHash(this.iframe)) && (t.replace || this.iframe.document.open().close(), this._updateHash(this.iframe.location, e, t.replace));
                }
                t.trigger && this.loadUrl(e);
            }
        },
        _updateHash: function(e, t, n)
        {
            if (n)
            {
                var i = e.href.replace(/(javascript:|#).*$/, "");
                e.replace(i + "#" + t);
            }
            else
            {
                e.hash = "#" + t;
            }
        }
    }),
    e.history = new P;
    var w = e.View = function(e)
    {
        this.cid = a.uniqueId("view"),
        this._configure(e || {}),
        this._ensureElement(),
        this.initialize.apply(this, arguments),
        this.delegateEvents();
    },
        N = /^(\S+)\s*(.*)$/,
        I = ["model", "collection", "el", "id", "attributes", "className", "tagName", "events"];
    a.extend(w.prototype, d, {
        tagName: "div",
        $: function(e)
        {
            return this.$el.find(e);
        },
        initialize: function()
        {
        },
        render: function()
        {
            return this;
        },
        remove: function()
        {
            return this.$el.remove(),
            this.stopListening(),
            this;
        },
        setElement: function(t, n)
        {
            return this.$el && this.undelegateEvents(),
            this.$el = t instanceof e.$ ? t : e.$(t),
            this.el = this.$el[0],
            n !== !1 && this.delegateEvents(),
            this;
        },
        delegateEvents: function(e)
        {
            if (e || (e = a.result(this, "events")))
            {
                this.undelegateEvents();
                for (var t in e)
                {
                    var n = e[t];
                    if (a.isFunction(n) || (n = this[e[t]]), !n)
                    {
                        throw Error('Method "' + e[t] + '" does not exist');
                    }
                    var i = t.match(N),
                        o = i[1],
                        s = i[2];
                    n = a.bind(n, this),
                    o += ".delegateEvents" + this.cid,
                    "" === s ? this.$el.on(o, n) : this.$el.on(o, s, n);
                }
            }
        },
        undelegateEvents: function()
        {
            this.$el.off(".delegateEvents" + this.cid);
        },
        _configure: function(e)
        {
            this.options && (e = a.extend({},
                a.result(this, "options"), e)),
            a.extend(this, a.pick(e, I)),
            this.options = e;
        },
        _ensureElement: function()
        {
            if (this.el)
            {
                this.setElement(a.result(this, "el"), !1);
            }
            else
            {
                var t = a.extend({},
                    a.result(this, "attributes"));
                this.id && (t.id = a.result(this, "id")),
                this.className && (t["class"] = a.result(this, "className"));
                var n = e.$("<" + a.result(this, "tagName") + ">").attr(t);
                this.setElement(n, !1);
            }
        }
    });
    var O = {
        create: "POST",
        update: "PUT",
        patch: "PATCH",
        "delete": "DELETE",
        read: "GET"
    };
    e.sync = function(t, n, i)
    {
        var o = O[t];
        a.defaults(i || (i = {}), {
            emulateHTTP: e.emulateHTTP,
            emulateJSON: e.emulateJSON
        });
        var s = {
            type: o,
            dataType: "json"
        };
        if (i.url || (s.url = a.result(n, "url") || M()), null != i.data || !n || "create" !== t && "update" !== t && "patch" !== t || (s.contentType = "application/json", s.data = JSON.stringify(i.attrs || n.toJSON(i))), i.emulateJSON && (s.contentType = "application/x-www-form-urlencoded", s.data = s.data ? {
            model: s.data
        } : {}), i.emulateHTTP && ("PUT" === o || "DELETE" === o || "PATCH" === o))
        {
            s.type = "POST",
            i.emulateJSON && (s.data._method = o);
            var r = i.beforeSend;
            i.beforeSend = function(e)
            {
                return e.setRequestHeader("X-HTTP-Method-Override", o),
                r ? r.apply(this, arguments) : void 0;
            };
        }
        "GET" === s.type || i.emulateJSON || (s.processData = !1);
        var l = i.success;
        i.success = function(e)
        {
            l && l(n, e, i),
            n.trigger("sync", n, e, i);
        };
        var u = i.error;
        i.error = function(e)
        {
            u && u(n, e, i),
            n.trigger("error", n, e, i);
        };
        var c = i.xhr = e.ajax(a.extend(s, i));
        return n.trigger("request", n, c, i),
        c;
    },
    e.ajax = function()
    {
        return e.$.ajax.apply(e.$, arguments);
    };
    var x = function(e, t)
    {
        var n, i = this;
        n = e && a.has(e, "constructor") ? e.constructor : function()
        {
            return i.apply(this, arguments);
        },
        a.extend(n, i, t);
        var o = function()
        {
            this.constructor = n;
        };
        return o.prototype = i.prototype,
        n.prototype = new o,
        e && a.extend(n.prototype, e),
        n.__super__ = i.prototype,
        n;
    };
    h.extend = p.extend = g.extend = w.extend = P.extend = x;
    var M = function()
    {
        throw Error('A "url" property or function must be specified');
    };
}).call(this);